﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DnPakExplorer.Controls {
	public partial class MyVScrollBar : UserControl {

		private int mValue;
		private bool mDragThum;
		private Point mMouseDownPosition;
		private int mMouseDownValue;
		private Sprite mBack;
		private Sprite mThum;
		private Image mTopButtonImage;
		private Image mBottomButtonImage;
		private bool mHover;
		//
		// 摘要: 
		//     在通过鼠标或键盘操作移动滚动框后发生。
		public new event ScrollEventHandler Scroll;
		//
		// 摘要: 
		//     当通过 System.Windows.Forms.ScrollBar.Scroll 事件或以编程方式更改 System.Windows.Forms.ScrollBar.Value
		//     属性时发生。
		public event EventHandler ValueChanged;

		public MyVScrollBar() {
			SetStyle(ControlStyles.DoubleBuffer
				| ControlStyles.AllPaintingInWmPaint
				| ControlStyles.ResizeRedraw
				| ControlStyles.SupportsTransparentBackColor
				| ControlStyles.UserPaint, 
				true);
			InitializeComponent();
			Width = 10;
			LargeChange = 10;
			SmallChange = 20;
			Maximum = 100;
			mTopButtonImage = Properties.Resources.scrollbar_buttom_top;
			mBottomButtonImage = Properties.Resources.scrollbar_button_bottom;
			mBack = new Sprite(Properties.Resources.scrollbar_background_vertical, 0, 2, 0, 2);
			mThum = new Sprite(Properties.Resources.scrollbar_thum_vertical, 0, 2, 0, 2);
		}

		private int ScrollButtonHeight {
			get { return 12; }
		}

		private int MinScrollThumSize {
			get { return 15; }
		}

		public int Minimum {
			get;
			set;
		}

		public int Maximum {
			get;
			set;
		}

		public int LargeChange {
			get;
			set;
		}

		public int SmallChange {
			get;
			set;
		}

		public int Value {
			get {
				return mValue;
			}
			set {
				int newValue = Math.Min(Maximum-LargeChange, Math.Max(Minimum, value));
				if (newValue != mValue) {
					mValue = newValue;
					if (ValueChanged != null) {
						ValueChanged(this, EventArgs.Empty);
					}
					Invalidate();
				}
			}
		}

		private void ScrollValue(int newValue, ScrollEventType type) {
			newValue = Math.Min(Maximum-LargeChange, Math.Max(Minimum, newValue));
			if (newValue != mValue) {
				int oldValue = mValue;
				mValue = newValue;
				if (Scroll != null) {
					Scroll(this, new ScrollEventArgs(type, oldValue, newValue, ScrollOrientation.VerticalScroll));
				}
				//Invalidate();
				Refresh();
			}
		}

		private int ScrollValueRangeLength {
			get { return Maximum-LargeChange-Minimum; }
		}

		private Rectangle TopButtonRect {
			get { return new Rectangle(0, 0, Width-1, ScrollButtonHeight); }
		}

		private Rectangle BottomButtonRect {
			get { return new Rectangle(0, Height-ScrollButtonHeight, Width-1, ScrollButtonHeight); }
		}

		private Rectangle ThumRect {
			get { return new Rectangle(0, CalculateThumPosion(), Width-1, CalculateThumSize()); }
		}

		// 游标大小（高度）
		private int CalculateThumSize(){
			int scrollSpace = (Height-ScrollButtonHeight*2);
			return Math.Min(Math.Max(MinScrollThumSize, scrollSpace*LargeChange/(Maximum-Minimum)), scrollSpace);
		}

		// 游标滚动坐标范围
		private int ScrollLength {
			get { return Height-ScrollButtonHeight*2-CalculateThumSize(); }
		}

		// 游标Y坐标
		private int CalculateThumPosion() {
			return ScrollLength*(Value-Minimum)/ScrollValueRangeLength+ScrollButtonHeight;
		}

		private void MyScrollBar_Paint(object sender, PaintEventArgs e) {
			if (mHover || mDragThum) {
				mBack.Draw(e.Graphics, ClientRectangle);
				mThum.Draw(e.Graphics, ThumRect);
			} else {
				mThum.Draw(e.Graphics, ThumRect);
				mBack.Draw(e.Graphics, ClientRectangle);
			}
			e.Graphics.DrawImage(mTopButtonImage, new Rectangle(0, 1, Width, ScrollButtonHeight-2));
			e.Graphics.DrawImage(mBottomButtonImage, new Rectangle(0, Height-ScrollButtonHeight+1, Width, ScrollButtonHeight-2));
		}

		private void MyScrollBar_MouseMove(object sender, MouseEventArgs e) {
			Invalidate();
			if (mDragThum) {
				int dy = e.Location.Y - mMouseDownPosition.Y;
				ScrollValue(dy*ScrollValueRangeLength/ScrollLength+mMouseDownValue, ScrollEventType.ThumbTrack);
			}
			mHover = ClientRectangle.Contains(e.Location);
			
		}

		private void MyScrollBar_MouseLeave(object sender, EventArgs e) {
			if (mDragThum) {
				mDragThum = false;
				Capture = false;
			}
			mHover = false;
			Invalidate();
		}

		private void MyScrollBar_MouseDown(object sender, MouseEventArgs e) {
			if (ThumRect.Contains(e.Location)) {
				mDragThum = true;
				Capture = true;
				mMouseDownPosition = e.Location;
				mMouseDownValue = Value;
			}
		}

		private void MyScrollBar_MouseUp(object sender, MouseEventArgs e) {
			if (mDragThum) {
				mDragThum = false;
				Capture = false;
			}
		}

		private void MyScrollBar_MouseClick(object sender, MouseEventArgs e) {
			if (e.Button == System.Windows.Forms.MouseButtons.Left) {
				if (TopButtonRect.Contains(e.Location)) {
					ScrollValue(Value-SmallChange, ScrollEventType.SmallDecrement);
				} else if (BottomButtonRect.Contains(e.Location)) {
					ScrollValue(Value+SmallChange, ScrollEventType.SmallIncrement);
				}
			}
		} 
	}
}
